package com.zyht.bank.manage.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.RandomStringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.wx.core.process.WxApi;
import com.wx.entity.SysWxuser;
import com.wx.service.SysWxTokenService;
import com.wx.service.SysWxuserService;
import com.zyht.bank.manage.entity.AxdQrcode;
import com.zyht.bank.manage.entity.AxdQrcodeExample;
import com.zyht.bank.manage.service.AxdQrcodeService;
import com.zyht.bank.manage.vo.AxdQrcodeVo;
import com.zyht.bank.service.AxdOrgInfoService;
import com.zyht.common.AbsManageBaseController;
import com.zyht.common.bean.PropertiesUtilBean.PropertiesUtils;
import com.zyht.common.intercepter.Token;
import com.zyht.common.util.ExcelUtil;
import com.zyht.common.util.HttpUtils;
import com.zyht.common.util.Page;
import com.zyht.wechat.framework.constant.ConfigConstants;

@Controller
@RequestMapping("/admin/qrcode")
public class AdminQrcodeCotroller extends AbsManageBaseController {
	@Resource
	private SysWxuserService sysWxuserService;

	@Resource
	private SysWxTokenService sysWxTokenService;

	@Resource
	private AxdOrgInfoService axdOrgInfoService;

	@Resource
	private AxdQrcodeService axdQrcodeService;

	private final MultiFormatWriter multiFormatWriter = new MultiFormatWriter();

	/**
	 * <b>作者:</b> sunpeng<br/>
	 * <b>修改时间：</b>2017年6月28日 <br/>
	 * <b>功能说明：</b>批量生成全部二维码<br/>
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */

	@RequestMapping("index")
	@Token(save = true)
	public String index(String orgName, String status, HttpServletRequest request, HttpServletResponse response,
			Model model, Integer currentPage) {

		int total = axdQrcodeService.findOrgAndCodeCount(orgName, null);
		if (null == currentPage || currentPage == 0) {
			currentPage = 1;
		}
		String url = PropertiesUtils.getConfig(ConfigConstants.PHONE_FILE_UPLOAD_URL);
		String pageSizeStr = PropertiesUtils.getConfig("paganation_page_size");
		int pageSize = Integer.valueOf(pageSizeStr);
		Page<AxdQrcodeVo> page = new Page<AxdQrcodeVo>(total, currentPage, pageSize);
		PageHelper.startPage(currentPage, pageSize);
		List<AxdQrcodeVo> axdOrgInfoList = axdQrcodeService.findOrgAndCode(orgName, null);
		axdOrgInfoList.forEach(org -> {
			org.setQrcodeUrl(url + org.getQrcodeUrl());

		});
		page.setRecordList(axdOrgInfoList);
		model.addAttribute("page", page);
		model.addAttribute("orgName", orgName);
		model.addAttribute("status", status);
		return "qrcode/index";

	}

	@RequestMapping("mass")
	public String massCreateQrcode(Integer[] idStr, HttpServletRequest request, HttpServletResponse response,
			Model model) {
		AxdQrcodeExample axdQrcodeExample = new AxdQrcodeExample();
		List<AxdQrcode> list = axdQrcodeService.list(axdQrcodeExample);
		int pageSize = 100;
		List<Integer> idList = new ArrayList<Integer>();
		if (list.size() == 0) {
			idList.addAll(Arrays.asList(idStr));
		} else {
			boolean flag = false;
			for (Integer id : idStr) {
				for (AxdQrcode axdQrcode : list) {
					if (axdQrcode.getOrgId() == id) {
						flag = false;
						break;
					} else {
						flag = true;
					}

				}
				if (flag) {
					idList.add(id);
				}

			}
		}
		if (idList.size() == 0) {
			return "redirect:index";
		}
		Integer count = idList.size();
		int pageCount = count.intValue() / pageSize + 1;

		String wxid = PropertiesUtils.getConfig("globle_default_wxid");
		SysWxuser wxinfo = this.sysWxuserService.selectByWxid(wxid);
		String accessToken = this.sysWxTokenService.getAccessToken(wxinfo);
		String requestUrl = WxApi.getRequestUrl(WxApi.QRCODE_CREATE, accessToken);

		String uploadPath = PropertiesUtils.getConfig(ConfigConstants.PHONE_FILE_UPLOAD_DIR);
		String qrPath = "/qr/";
		uploadPath = uploadPath + qrPath;
		File uploadFolder = new File(uploadPath);
		if (!uploadFolder.exists()) {
			uploadFolder.mkdirs();
		}
		final String absPath = uploadFolder.getAbsolutePath();
		for (int pageIndex = 1; pageIndex <= pageCount; pageIndex++) {
			int toEndIndex = pageIndex * pageSize;
			if (toEndIndex >= count) {
				toEndIndex = count;
			}
			final List<Integer> subIdList = idList.subList((pageIndex - 1) * pageSize, toEndIndex);

			List<AxdQrcode> qrList = new ArrayList<AxdQrcode>(subIdList.size());
			for (Integer id : subIdList) {
				String content = createQRCodeContent(requestUrl,
						"axd_org_" + axdOrgInfoService.findOneById(id).getOrgCode());
				if (null == content) {
					continue;
				}
				AxdQrcode bean = new AxdQrcode();
				bean.setOrgId(id);
				bean.setQrInfoUrl(content);
				String fileName = createQrCode(absPath, content);
				if (null != fileName) {
					bean.setQrcodeurl(qrPath + fileName);
					qrList.add(bean);
				}
			}
			axdQrcodeService.doBatchInsert(qrList);

		}

		return "redirect:index";
	}

	private String createQRCodeContent(String url, String scene) {
		String outputStr = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \""
				+ scene + "\"}}}";
		String content = null;
		try {
			String jsonStr = HttpUtils.post(url, outputStr);
			JSONObject json = JSONObject.parseObject(jsonStr);
			if (json.containsKey("errcode")) {
				logger.error("The scene[" + scene + "] is try create the ticket, but fail!");
				logger.error("获取生成永久二维码ticket错误：" + json.getString("errmsg"));
			} else {
				content = json.getString("url");
			}
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("The scene[" + scene + "] is try create the ticket, but fail!");
		}
		return content;
	}

	/*
	 * 返回二维码名称
	 */
	private String createQrCode(String uploadPath, String content) {
		String fileName = RandomStringUtils.random(4, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + "_"
				+ System.currentTimeMillis() + ".png";
		try {
			String realPath = uploadPath + File.separator + fileName;
			FileOutputStream fos = new FileOutputStream(realPath);

			int width = 450;
			int height = 450;
			String format = "png";

			BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, width, height);
			MatrixToImageWriter.writeToStream(bitMatrix, format, fos);
			if (fos != null) {
				fos.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			fileName = null;
		} catch (IOException e) {
			e.printStackTrace();
			fileName = null;
		} catch (WriterException e) {
			e.printStackTrace();
			fileName = null;
		}

		return fileName;
	}

	@RequestMapping("export")
	public void export(Integer flag, Integer currentPage, String orgName, String status, Date startDate, Date endDate,
			HttpServletRequest request, HttpServletResponse response) {
		// 0: 导出当前页 , null 或者 1, 导出全部
		if (null != flag && flag == 0) {
			if (null == currentPage || currentPage <= 0) {
				currentPage = 1;
			}
			Integer pageSize = getPageSize();
			PageHelper.startPage(currentPage, pageSize);
		}
		if (null != endDate)
			endDate = new Date(endDate.getTime() + 24 * 60 * 60 * 1000);
		List<AxdQrcodeVo> list = axdQrcodeService.findOrgAndCode(orgName, status);
		try {
			createExcel(response, list);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public void createExcel(HttpServletResponse response, List<AxdQrcodeVo> list) throws IOException {
		// 转换map
		List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("sheetName", "sheet1");
		listmap.add(map);
		if (list != null && list.size() > 0) {
			for (AxdQrcodeVo vo : list) {
				Map<String, Object> mapValue = new HashMap<String, Object>();
				mapValue.put("orgName", vo.getOrgName());
				mapValue.put("qrcodeUrl", vo.getQrcodeUrl());

				listmap.add(mapValue);
			}

		}
		// 生成excel
		String columnNames[] = { "机构名称", "二维码图片" };// 列名
		String keys[] = { "orgName", "qrcodeUrl" };// map中的key
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			ExcelUtil.createWorkBook(listmap, keys, columnNames).write(os);
		} catch (IOException e) {
			e.printStackTrace();
		}
		byte[] content = os.toByteArray();
		InputStream is = new ByteArrayInputStream(content);
		// 设置response参数，可以打开下载页面
		response.reset();
		response.setContentType("application/vnd.ms-excel;charset=ISO8859_1");
		response.setHeader("Content-Disposition",
				"attachment;filename=" + new String(("ScratchCardsRecord" + ".xls").getBytes(), "ISO8859_1"));
		ServletOutputStream out = response.getOutputStream();
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(out);
			byte[] buff = new byte[2048];
			int bytesRead;
			// Simple read/write loop.
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
			}
		} catch (final IOException e) {
			throw e;
		} finally {
			if (bis != null)
				bis.close();
			if (bos != null)
				bos.close();
		}
	}

}
